package com.cloud.pay.payment;

import com.cloud.common.util.JsonUtils;
import com.cloud.pay.config.AppConfig;
import com.cloud.pay.constant.PayChannelEnum;
import com.cloud.pay.entity.PayConfig;
import com.cloud.pay.entity.Payment;
import com.cloud.pay.entity.Refund;
import com.egzosn.pay.ali.api.AliPayConfigStorage;
import com.egzosn.pay.ali.api.AliPayService;
import com.egzosn.pay.ali.bean.AliTransactionType;
import com.egzosn.pay.common.bean.PayOrder;
import com.egzosn.pay.common.bean.PayOutMessage;
import com.egzosn.pay.common.bean.RefundOrder;
import com.egzosn.pay.common.http.HttpConfigStorage;
import com.egzosn.pay.common.util.sign.SignUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.InputStream;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Component
public class AliPayAdapter implements PayAdapter {

    private Map<String, AliPayService> aliPayServiceMap = new HashMap<>();
    private Map<String, String> configMap = new HashMap<>();

    @Autowired
    private AliPayBackHandler aliPayBackHandler;

    @Autowired
    private AppConfig appConfig;

    @Override
    public String getQrcode(Payment payment) {
        AliPayService payService = aliPayServiceMap.get(payment.getAppId());
        if (payService == null) {
            log.info("no appId {}", payment.getAppId());
            return null;
        }
        PayOrder payOrder = new PayOrder(payment.getPayTitle(), "", new BigDecimal(payment.getPayMoney() / 100), payment.getOrderNo(), AliTransactionType.SWEEPPAY);
        return payService.getQrPay(payOrder);
    }

    @Override
    public String orderInfo(Payment payment) {
        AliPayService payService = aliPayServiceMap.get(payment.getAppId());
        if (payService == null) {
            log.info("no appId {}", payment.getAppId());
            return null;
        }
        PayOrder payOrder = new PayOrder(payment.getPayTitle(), "", new BigDecimal(payment.getPayMoney() / 100), payment.getOrderNo(), AliTransactionType.APP);
        return JsonUtils.toJSONString(payService.orderInfo(payOrder));
    }

    @Override
    public boolean refund(Refund refund) {
        AliPayService payService = aliPayServiceMap.get(refund.getAppId());
        if (payService == null) {
            log.info("no appId {}", refund.getAppId());
            return false;
        }
        RefundOrder refundOrder = new RefundOrder(refund.getRefundNo(), refund.getTradeNo(), new BigDecimal(refund.getRefundMoney() / 100));
        refundOrder.setTotalAmount(refundOrder.getRefundAmount());
        Map response = payService.refund(refundOrder);
        Map result = (Map) response.get("alipay_trade_refund_response");
        if (AliPayService.SUCCESS_CODE.equals(result.get(AliPayService.CODE))) {
            return true;
        }
        return false;
    }

    @Override
    public PayOutMessage payBack(String appId, Map<String, String[]> parameterMap, InputStream input) {
        AliPayService payService = aliPayServiceMap.get(appId);
        if (payService == null) {
            log.info("no appId {}", appId);
            return null;
        }
        return payService.payBack(parameterMap, input);
    }

    @Override
    public void loadConfig(List<PayConfig> list) {
        for (PayConfig payConfig : list) {
            if (PayChannelEnum.of(payConfig.getChannel()) != PayChannelEnum.ALI_PAY) {
                continue;
            }
            String configJson = JsonUtils.toJSONString(payConfig);
            String configs = configMap.get(payConfig.getAppId());
            if (configs == null || !configs.equals(configJson)) {
                aliPayServiceMap.put(payConfig.getAppId(), createAliPayService(payConfig));
                configMap.put(payConfig.getAppId(), configJson);
            }
        }
    }

    /**
     * 创建支付宝服务
     *
     * @param payConfig
     */
    private AliPayService createAliPayService(PayConfig payConfig) {
        AliPayConfigStorage aliPayConfigStorage = new AliPayConfigStorage();
        aliPayConfigStorage.setAppid(payConfig.getAppId());
        aliPayConfigStorage.setKeyPublic(payConfig.getApiSecretkey());
        aliPayConfigStorage.setKeyPrivate(payConfig.getPrivateKey());
        aliPayConfigStorage.setNotifyUrl(appConfig.getWxPayNotifyUrl().replace("appId", payConfig.getAppId()));
        aliPayConfigStorage.setSignType(SignUtils.RSA2.name());
        aliPayConfigStorage.setInputCharset("utf-8");

        log.info("createAliPayService appId >>>" + aliPayConfigStorage.getAppid());

        // 请求连接池配置
        HttpConfigStorage httpConfigStorage = new HttpConfigStorage();
        httpConfigStorage.setMaxTotal(20);
        httpConfigStorage.setDefaultMaxPerRoute(10);

        AliPayService payService = new AliPayService(aliPayConfigStorage, httpConfigStorage);
        payService.setPayMessageHandler(aliPayBackHandler);
        return payService;
    }
}
